const path = require("path");
const fs = require("fs");
// const os = require("os");
const htmlPlugin = require("html-webpack-plugin");
const AddAssetHtmlPlugin = require("add-asset-html-webpack-plugin");
const webpack = require("webpack");
const { VueLoaderPlugin } = require("vue-loader");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const CssMinimizerWebpackPlugin = require("css-minimizer-webpack-plugin");
const { CleanWebpackPlugin } = require("clean-webpack-plugin");

const plugins = [
  new htmlPlugin({
    title: "webpack5+vue3",
    filename: "index.html",
    template: path.resolve("index.html"),
  }),

  new VueLoaderPlugin(),
  new MiniCssExtractPlugin({
    filename: path.posix.join("./", "css/[hash]-[name].css"),
  }),
  new CssMinimizerWebpackPlugin(),
  new CleanWebpackPlugin(),
  new webpack.DllReferencePlugin({
    context: __dirname,
    manifest: path.resolve(__dirname, "./vendors.manifest.json"),
  }),
];

const files = fs.readdirSync(path.resolve(__dirname, "./dll"));

files.forEach((file) => {
  if (/.*\.dll.js$/.test(file)) {
    plugins.push(
      new AddAssetHtmlPlugin({
        filepath: path.resolve(__dirname, "./dll", file),
        outputPath: "./dll",
      })
    );
  }
});

// const cpuLen = os.cpus();

// const threadLoader = {
//   loader: "thread-loader",
//   options: {
//     works: cpuLen.length - 1,
//   },
// };

module.exports = {
  entry: "./src/main.ts",
  output: {
    filename: "./js/[name].js",
    path: path.resolve(__dirname, "dist"),
  },
  resolve: {
    extensions: [".vue", ".js", ".json", ".ts"],
    alias: {
      "@": path.resolve(__dirname, "src"),
    },
  },
  mode: "production",
  module: {
    rules: [
      {
        test: /\.ts$/,
        use: [
          {
            loader: "ts-loader",
            options: {
              appendTsSuffixTo: [/\.vue$/],
              transpileOnly: true,
            },
          },
        ],
      },
      {
        test: /\.vue$/,
        exclude: /node_modules/,
        use: [
          {
            loader: "vue-loader",
          },
        ],
      },
      {
        test: /\.css$/,
        use: [MiniCssExtractPlugin.loader, "css-loader"],
      },
      {
        test: /\.less$/,
        use: [
          MiniCssExtractPlugin.loader,
          "css-loader",
          {
            loader: "less-loader",
          },
        ],
      },
    ],
  },
  plugins,
  optimization: {
    minimize: process.env.NODE_ENV === "production" ? true : false, // 开发环境不压缩
    splitChunks: {
      chunks: "all",
      minSize: 20000,
      minRemainingSize: 0,
      minChunks: 1,
      maxAsyncRequests: 30,
      maxInitialRequests: 30,
      enforceSizeThreshold: 50000,
      cacheGroups: {
        defaultVendors: {
          test: /[\\/]node_modules[\\/]/,
          priority: -10,
          reuseExistingChunk: true,
        },
        default: {
          minChunks: 2,
          priority: -20,
          reuseExistingChunk: true,
        },
        "element-plus": {
          name: "chunk-elem", // 单独将 elementUI 拆包
          priority: 15, // 权重需大于其它缓存组
          test: /[\\/]node_modules[\\/]element-plus[\\/]/,
        },
      },
    },
  },
};
